package cn.tedu.sp06.filter;

import cn.tedu.sp01.util.JsonResult;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 网关过滤器层面添加校验功能
 */
@Component
@Slf4j
public class AccessFilter extends ZuulFilter {
    /**
     * 过滤器的类型: pre , routing , post , error
     *
     * @return
     */
    @Override
    public String filterType() {
        //return "pre";
        return FilterConstants.PRE_TYPE;//前置过滤器
    }

    /**
     * 顺序号 : 添加的位置
     *
     * @return 6
     * <br>Zuul默认有五个过滤器,
     * <br>在第五个过滤器中,向上下文对象添加了 serviceId 属性,后面的过滤器才能访问serviceId
     */
    @Override
    public int filterOrder() {
        return 6;//默认已经有五个过滤器,加在前置过滤器第六个
    }

    /**
     * 判断针对当前请求,是否执行过滤代码
     * <br>
     * 针对 : 请求商品要检查权限,请求用户和订单不检查权限
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        //判断当前调用的后台服务,是否为 item-service

        //1. 获取调用的服务id
        RequestContext currentContext = RequestContext.getCurrentContext();//获取Zuul的上下文对象
        //currentContext.get("serviceId");
        String serviceId = (String) currentContext.get(FilterConstants.SERVICE_ID_KEY);

        //2. 如果id为 item-service 返回true
        return "item-service".equals(serviceId);
    }

    /**
     * 过滤代码
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        //判断是否携带有token
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String token = request.getParameter("token");

        //如果没有token ,阻止继续调用,直接返回响应
        if (StringUtils.isBlank(token)) {
            //阻止继续调用
            currentContext.setSendZuulResponse(false);

            //返回响应 JsonResult -- {code : xx, msg : xx, data : null}
            String jsonStr = JsonResult
                    .err()
                    .code(JsonResult.NOT_LOGIN)
                    .msg("未登录")
                    .toString();
            currentContext.addZuulResponseHeader(
                    "Content-Type", "application/json;charset=UTF-8");
            currentContext.setResponseBody(jsonStr);
        }
        //Zuul 当前版本没有使用这个返回值,它不起任何作用
        return null;
    }
}
